<!DOCTYPE html>
<html lang="zh-cn">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>文件下载器</title>
</head>
<body>
  <div>
    <button onclick="downLoad()" id="start">开始</button>
    <button onclick="stopDownLoad()" id="stop">暂停</button>
  </div>
  <script type="text/javascript">
    let controller
    let chunks = []
    let rangLength = 0
    let total = 0
    const cacheChunksHandle = async (res) => {
      if (!rangLength) {
        total = res.headers.get('content-length')
      }
      console.log('total--->', total)
      const reader = res.body.getReader()
      const stream = new ReadableStream({
        async start(controller){
          const readLoop = async () => {
            const { value, done } = await reader.read()
            if(done) {
              let chunk
              while (chunk = chunks.shift()) {
                controller.enqueue(chunk)
              }
              controller.close()
              return 
            }
            chunks.push(value)
            rangLength += value.length
            console.log(`Downloaded ${rangLength} of ${total} (${(rangLength / total * 100).toFixed(2)}%)`)
            await readLoop()
          }
          await readLoop()
        }
      })
      return new Response(stream, { headers: res.headers })
    }

    downLoad = async () => {
      try {
        controller = new AbortController()
        const { signal } = controller
        const res = await fetch('./test.json', {
          headers: {
            'Range': `bytes=${rangLength}`
          },
          signal
        })
        const logResult = await cacheChunksHandle(res)
        const jsonData = await logResult.json()
        console.log('readerDownload json--->', jsonData)
      } catch (error) {
        console.log('error--->', error)
      }
      
    }
    const stopDownLoad = () => {
      controller.abort()
    }
  </script>
</body>
</html>